package edu.amm.fanal.api;

import edu.amm.api.Bounds;

/**
 * Пространство функций, заданных на отрезке.
 * 
 * @author Иванов Илья
 * @since 2013-05-12
 *
 */
public abstract class FunctionalSpace extends Bounds {
	
	/**
	 * Создаёт функциональное пространство на заданном отрезке.
	 * 
	 * @param bounds Границы отрезка.
	 */
	public FunctionalSpace(Bounds bounds) {
		super(bounds);
	}
	
	/**
	 * @param elem Элемент пространства.
	 * @return Значение нормы элемента.
	 */
	public double norm(Function elem) {
		if (elem == null)
			throw new RuntimeException("Не задан элемент пространства для вычисления нормы");
		
		return getNorm(elem);
	}
	
	/**
	 * @return Название пространства.
	 */
	public abstract String getSpaceName();
	
	/**
	 * @param elem Элемент пространства.
	 * @return Значение нормы элемента.
	 */
	protected abstract double getNorm(Function elem);
	
	/**
	 * Тип функционального пространства.
	 * 
	 * @author Иванов Илья
	 * @since 2013-05-12
	 *
	 */
	public static enum SpaceType {
		
		/**
		 * Пространство Лебега L2.
		 */
		LEBESGUE {
			
			protected FunctionalSpace getInstance(Bounds bounds) {
				return new LebesgueSpace(bounds);
			}
		};
		
		/**
		 * Создаёт функциональное пространство на заданном отрезке.
		 * 
		 * @param bounds Границы отрезка.
		 * @return Созданное пространство.
		 */
		public FunctionalSpace instantiate(Bounds bounds) {
			if (bounds == null)
				throw new RuntimeException("Не заданы границы отрезка для функционального пространства");
			
			return getInstance(bounds);
		}
		
		protected abstract FunctionalSpace getInstance(Bounds bounds);
	}
}